//Document Object Model (DOM)
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

//DOM to XML Serialization
import Engine.Action;
import Engine.Coordinate;
import Engine.Player;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

//Base imports
import java.net.*;
import java.io.*;
import java.util.*;

public class ActionHandler implements Runnable {
    
    private Socket sin;
    private Socket sout;
    private int ID;
    private Document dom;
    private InputStream is;
    private OutputStream os;
    private Player currentPlayer;
    private ArrayList<Player> players;

    ActionHandler(ArrayList<Player> players, Socket sin, Socket sout, int ID) {
		this.players = players;
		this.ID = ID;
	
		this.sin = sin;
		this.sout = sout;
    }

    public void run() {
	
		try {
	
		    /**
		     * Create GameClient/GameServer Connections
		     */
		    is = sin.getInputStream();
		    os = sout.getOutputStream();
	
		    /**
		     *
		     * Recieve Action From GameClient
		     *
		     */
	
		    /** Create document object model from XML parse */
		    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		    DocumentBuilder db = dbf.newDocumentBuilder();
		    dom = db.parse(is);
		    is.close();
		    
		    /** Create Action object from DOM parse */
			String actionID = getTextValue(dom.getDocumentElement(),"ActionID");
			String playerID = getTextValue(dom.getDocumentElement(),"PlayerID");
			
			System.out.println("action ID = "+actionID+", playerID  = "+playerID);

			if(actionID.equals("register"))
			{
				currentPlayer = new Player(playerID);
				players.add(currentPlayer);
				currentPlayer.getProperties().set_latLong(new Coordinate(dom.getDocumentElement()));
			}
			else
			{
				for (Player p : players) {
					if(playerID.equals(p.getId()))
					{
						currentPlayer = p; 
					}
				}
				currentPlayer.getProperties().set_latLong(new Coordinate(dom.getDocumentElement()));
				
				for (Action a : currentPlayer.getAvailableAction()) {
					if(a.getId().equals(actionID))
					{
						if(a.TestAvailability(currentPlayer))
							a.Do(currentPlayer);
					}
				}
			}
			
		    /**
		     *
		     * Update GameState
		     *
		     */
			GameState gs = new GameState(currentPlayer);
	
		    /**
		     *
		     * Send GameState to GameClient
		     *
		     */
		    
		    /** Create GameState DOM of Engine */
		    dbf = DocumentBuilderFactory.newInstance();
		    db = dbf.newDocumentBuilder();
		    dom = db.newDocument();
		    Element rootEle = gs.toXmlElement(dom);     
		    dom.appendChild(rootEle);
		    
		    
		    /** Set XML Formatting */
		    OutputFormat format = new OutputFormat(dom);
		    format.setIndenting(true);
	
		    /** Transmit Serialized XML from GameState DOM */
		    XMLSerializer serializer = new XMLSerializer(os, format);
		    serializer.serialize(dom);
		    
		    serializer = new XMLSerializer(System.out, format);
		    serializer.serialize(dom);
		    os.close();
	
		}catch(ParserConfigurationException pce) {
		    pce.printStackTrace();
		}catch(SAXException se) {
		    se.printStackTrace();
		}catch(IOException ioe) {
		    ioe.printStackTrace();
		}catch (Exception e) {
		    System.out.println(e.getMessage());
		}
	
		finally {
		    
		    try {
			sin.close();
			sout.close();
		    }
		    catch (IOException e){}
		}

    }
    private String getTextValue(Element ele, String tagName) {
		String textVal = null;
		NodeList nl = ele.getElementsByTagName(tagName);
		if(nl != null && nl.getLength() > 0) {
		    return nl.item(0).getAttributes().getNamedItem("value").getNodeValue();
		}
		
		return null;
    }
    
    Player findCustomerByid(String id){
        for (int i=0; i<this.players.size(); i++) {
        	Player player = this.players.get(i);
            if (player.getId() == id){
                 return player;
            }
        }
        return null; // no Customer found with this ID; maybe throw an exception
    }


    
}


